<template>
  <div class="container">
    <div class="app-container">
      <el-button type="primary" size="mini" @click="show = true">添加角色</el-button>
      <!-- 表格 -->
      <el-table :data="list" style="margin: 20px 0">
        <el-table-column label="角色" prop="name">
          <template #default="obj">
            <el-input v-if="obj.row.isEdit" v-model="obj.row.editRow.name" size="mini" />
            <span v-else>{{ obj.row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column label="启用">
          <template #default="obj">
            <el-switch v-if="obj.row.isEdit" v-model="obj.row.editRow.state" :active-value="1" :inactive-value="0" />
            <span v-else> {{ obj.row.state === 1 ? '已启用' : '未启用' }}</span>
          </template>
        </el-table-column>
        <el-table-column label="描述" prop="description">
          <template #default="obj">
            <el-input v-if="obj.row.isEdit" v-model="obj.row.editRow.description" size="mini" type="textarea" />
            <span v-else>{{ obj.row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="obj">
            <!-- {{ obj.row }} -->
            <template v-if="obj.row.isEdit">
              <el-button type="primary" size="mini" @click="update(obj.row)">确认</el-button>
              <el-button size="mini" @click="cancel(obj.row)">取消</el-button>
            </template>

            <template v-else>
              <el-button type="text" @click="showAssignRightsDiaolg(obj.row.id)">分配权限</el-button>
              <el-button type="text" style="margin-right: 10px" @click="obj.row.isEdit = true">编辑</el-button>
              <!-- 气泡弹窗 -->
              <el-popconfirm
                title="确定删除该角色么?"
                @onConfirm="confirm(obj.row)"
              >
                <template #reference>
                  <el-button type="text">删除</el-button>
                </template>
              </el-popconfirm>
            </template>

          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <el-pagination
        style="float: right"
        :current-page="queryParams.page"
        :page-sizes="[1, 2, 3, 4]"
        :page-size="queryParams.pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
      <!-- 新增角色对话框 -->
      <el-dialog
        title="新增角色"
        :visible.sync="show"
        width="50%"
        @close="close"
      >
        <!-- 表单 -->
        <el-form ref="formRef" label-width="80px" :model="form" :rules="rules">
          <el-form-item label="角色名称" prop="name">
            <el-input v-model="form.name" placeholder="请输入角色名称" />
          </el-form-item>
          <el-form-item label="启用">
            <el-tooltip :content="`状态: ${form.state === 1 ? '已启用' : '未启用'}`" placement="top">
              <el-switch
                v-model="form.state"
                :active-value="1"
                :inactive-value="0"
              />
            </el-tooltip>
          </el-form-item>
          <el-form-item label="角色描述" prop="description">
            <el-input v-model="form.description" type="textarea" placeholder="请输入角色描述" />
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="close">取 消</el-button>
          <el-button type="primary" @click="submit">确 定</el-button>
        </span>
      </el-dialog>
      <!-- 为角色分配权限的对话框 -->
      <el-dialog title="分配权限" :visible.sync="visible">
        <!-- show-checkbox 展示复选框  check-strictly 父子互不关联-->
        <el-tree
          ref="treeRef"
          node-key="id"
          :data="treeData"
          :props="{label: 'name'}"
          default-expand-all
          show-checkbox
          check-strictly
          :default-checked-keys="permIds"
        />
        <div style="text-align: center;">
          <el-button type="primary" size="mini" @click="handleSubmit">确定</el-button>
          <el-button size="mini" @click="visible = false">取消</el-button>
        </div>
      </el-dialog>
    </div>
  </div>
</template>
<script>
// 1. 添加角色按钮绑定点击事件
// 2. 准备一个对话框组件
// 3. 添加按钮 将布尔值设置为true
// 4. 绘制表单结构

// 确定按钮绑定事件
// 1. 准备接口
// 2. 发送请求 角色id 权限点的id数组?????
// 3. 提示
// 4.关闭对话框
import { getRolesList, addRole, updateRole, delRole, getRoleDetail, assignRights } from '@/api/role'
import { getPermissionList } from '@/api/permission'
import { transformToTreedata } from '@/utils'
export default {
  name: 'Role',
  data() {
    return {
      list: [], // 角色列表
      total: 0, // 总数
      queryParams: { page: 1, pagesize: 2 },
      show: false, // 控制新增角色对话框的布尔值
      form: {
        name: '',
        state: 1,
        description: ''
      },
      rules: {
        name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
        description: [{ required: true, message: '角色描述不能为空', trigger: 'blur' }]
      },
      visible: false, // 为角色分配权限控制的布尔值
      treeData: [],
      id: '',
      permIds: []
    }
  },
  created() {
    this.getRolesList()
  },
  methods: {
    // 获取所有角色列表
    async getRolesList() {
      const res = await getRolesList(this.queryParams)
      // 遍历响应的数据, 为每一个数据添加一个布尔值
      res.data.rows.forEach(item => {
        item.isEdit = false
        // 将要修改的三个字段缓存
        item.editRow = {
          name: item.name,
          description: item.description,
          state: item.state
        }
      })
      this.list = res.data.rows
      this.total = res.data.total
      // vue2的问题 对数组元素的复杂数据类型 后续添加 isEdit 是非响应式的数据 defineProperty  proxy
      // $set的方法 this.$set(修改的对象, 设置的字段属性, 值)
      // this.list.forEach(item => { this.$set(item, 'isEdit', false) })
    },
    // pagesize发生变化的处理函数
    handleSizeChange(val) {
      // console.log(val)
      this.queryParams.pagesize = val
      this.queryParams.page = 1
      this.getRolesList()
    },
    // page发生变化的处理函数
    handleCurrentChange(val) {
      // console.log(val)
      this.queryParams.page = val
      this.getRolesList()
    },
    // 关闭并重置的方法
    close() {
      this.show = false
      this.$refs.formRef.resetFields()
    },

    // 新增角色
    submit() {
      // 1. 预校验
      this.$refs.formRef.validate(async boo => {
        if (boo) {
          // 2.发送请求
          await addRole(this.form)
          // 3. 提示
          this.$message.success('新增角色成功')
          //  4. 关闭对话框并重置
          this.close()
          //  5. 重新获取
          this.getRolesList()
        }
      })
    },
    // 取消编辑
    cancel(row) {
      row.isEdit = false
      // 将editRow初始化为原来的状态
      row.editRow = {
        name: row.name,
        description: row.description,
        state: row.state
      }
    },
    // 更新角色信息
    async update(row) {
      // 1. 校验必填
      if (!row.editRow.name.trim()) return this.$message.warning('请输入角色名称')
      if (!row.editRow.description.trim()) return this.$message.warning('请输入角色描述')
      // 2. 发送请求
      await updateRole({ ...row.editRow, id: row.id })
      // 3. 提示
      this.$message.success('角色更新成功')
      // 4.关闭编辑状态 发送完请求后 又去更新了数据 警告
      /*  row.isEdit = false
      // 5.更新视图
      // 重新获取 this.getRolesList() 额外多发一次请求
      // 直接将editRow的数据字段同步给row里面的字段
      row.name = row.editRow.name
      row.description = row.editRow.description
      row.state = row.editRow.state */
      // 对象合并 ,后者覆盖前者
      Object.assign(row, {
        isEdit: false,
        name: row.editRow.name,
        state: row.editRow.state,
        description: row.editRow.description
      })
    },
    // 确定删除角色
    async confirm(row) {
      // console.log('删除角色')
      // 1. 发送请求
      await delRole(row.id)
      // 2. 提示
      this.$message.success('删除成功')
      // 如果当前只剩一条数据了, 让queryParams.page--
      if (this.list.length === 1 && this.queryParams.page > 1) {
        this.queryParams.page--
      }
      // 3. 重新获取
      this.getRolesList()
    },
    // 展示分配权限的对话框
    async showAssignRightsDiaolg(id) {
      this.permIds = [] // 更保险的方式 每次打开前先清空数组
      this.id = id // 记录角色id
      const res = await getPermissionList()
      this.treeData = transformToTreedata(res.data, 0)
      const { data: { permIds }} = await getRoleDetail(id)
      this.permIds = permIds
      this.visible = true
      // console.log(permIds)
      // 调用树形数据的 setCheckedKeys([3])方法 数组是当前角色的详情信息 permIds 已有的权限点数组
      // this.$nextTick(() => {
      //   this.$refs.treeRef.setCheckedKeys(permIds)
      // })
    },
    // 为角色分配权限
    async handleSubmit() {
      // 1. 发送请求 携带参数
      // console.log(this.$refs.treeRef.getCheckedKeys()) // 勾选权限列表id数组
      await assignRights({ id: this.id, permIds: this.$refs.treeRef.getCheckedKeys() })
      // 2.提示
      this.$message.success('为角色分配权限成功')
      // 3. 关闭对话框
      this.visible = false
    }
  }
}
</script>
